home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Commodities / BlackHole / Source / delete.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-27  |  6.5 KB  |  269 lines

  1.  
  2. /*
  3.  * Delete.c -- for BlackHole.c.
  4.  * $Revision: 1.1
  5.  */
  6.  
  7. #include "header.h"
  8. #include "prog-protos.h"
  9.  
  10. /* Prototypes */
  11. Prototype LONG delete (struct HoleArg *);
  12.  
  13. Local LONG delete_file (struct WBArg *);
  14. Local LONG delete_icon (struct WBArg *);
  15. Local LONG delete_dir (struct WBArg *);
  16. Local LONG delete_contents (BPTR , BOOL );
  17.  
  18. /* Globals */
  19. BOOL ignore_protection;
  20.  
  21. #define EXALL_NUM 16            /* examine 16 files at a time (I think) */
  22.  
  23. /* Entry point */
  24. LONG delete (struct HoleArg *harg)
  25. {
  26.     set_current (NULL, SET_START);  /* reset current file */
  27.     ignore_protection = harg->prefs.ignore_prot;
  28.     return (delete_file (&(harg->wbarg)));
  29. }
  30.  
  31. /* Local functions */
  32.  
  33. /* delete_contents -- delete the contents of a directory with lock lock.    */
  34. /* If byicons is FALSE, search for ~(#?.info) & delete both name found and  */
  35. /* name.info, if byicons is true, delete any file of pattern #?.info        */
  36. LONG delete_contents (BPTR lock, BOOL byicons)
  37. {
  38.     BPTR old_lock = CurrentDir (lock);
  39.  
  40.     struct ExAllControl *eac = 0;
  41.     struct ExAllData *eadata = 0;
  42.     struct WBArg *arg = 0;
  43.     LONG error = 0;
  44.     BOOL more;
  45.     BYTE pattern[50];
  46.  
  47.     if (!(eac = (struct ExAllControl *) AllocDosObject (DOS_EXALLCONTROL, NULL)))
  48.     goto fail;
  49.     if (!(eadata = (struct ExAllData *)
  50.     malloc (EXALL_NUM * sizeof (struct ExAllData)))) goto fail;
  51.     if (!(arg = (struct WBArg *)malloc (sizeof (struct WBArg)))) goto fail;
  52.  
  53.     if (byicons) ParsePatternNoCase ("#?.info", pattern, 49);
  54.     else ParsePatternNoCase ("~(#?.info)", pattern, 49);
  55.  
  56.     eac->eac_LastKey = 0;
  57.     eac->eac_MatchString = pattern;
  58.     eac->eac_MatchFunc = NULL;
  59.  
  60.     do {
  61.     register struct ExAllData *ead;
  62.  
  63.     more = ExAll (lock, eadata, EXALL_NUM * sizeof (struct ExAllData),
  64.              ED_TYPE, eac);
  65.     if (!more)
  66.     {
  67.         if ((error = IoErr()) != ERROR_NO_MORE_ENTRIES) break;
  68.         else error = 0;
  69.     }
  70.  
  71.     if (eac->eac_Entries == 0) continue;    /* have we finished? */
  72.  
  73.     ead = eadata;
  74.  
  75.     do {
  76.         if (ead->ed_Type >=0)       /* is it a directory? */
  77.         {
  78.         arg->wa_Lock = Lock (ead->ed_Name, SHARED_LOCK);
  79.         arg->wa_Name = NULL;
  80.         if (arg->wa_Lock)
  81.         {
  82.             if (error = delete_file (arg))
  83.             {
  84.             more = FALSE; break;
  85.             UnLock (arg->wa_Lock);
  86.             }
  87.         }
  88.         }
  89.         else            /* it must be a file. */
  90.         {
  91.         arg->wa_Lock = lock;
  92.         arg->wa_Name = ead->ed_Name;
  93.  
  94.         if (byicons)
  95.         {
  96.             if (error = delete_icon (arg))
  97.             {
  98.             more = FALSE; break;
  99.             }
  100.         }
  101.         else
  102.         {
  103.             if (error = delete_file (arg))
  104.             {
  105.             more = FALSE; break;
  106.             }
  107.         }
  108.         }
  109.     } while (ead = ead->ed_Next);   /* go to next entry */
  110.  
  111.     } while (more);                     /* take next read from ExAll */
  112.  
  113.     fail:
  114.  
  115.     if (arg) free (arg);
  116.     else error = ERROR_NO_FREE_STORE;
  117.     if (eadata) free (eadata);
  118.     if (eac) FreeDosObject (DOS_EXALLCONTROL, eac);
  119.     CurrentDir (old_lock);
  120.  
  121.     return (error);
  122. }
  123.  
  124.  
  125. /* delete_dir -- delete a directory from lock. lock MUST be a directory     */
  126. /* or else! Returns an error from IoErr(), or 0 for ok.                     */
  127. LONG delete_dir (struct WBArg *wa)
  128. {
  129.     LONG error = 0;
  130.     char buf[256];
  131.     struct WBArg *parent = 0;
  132.  
  133.     if (error = delete_contents (wa->wa_Lock, FALSE)) goto fail;   /* delete files with/without icons */
  134.     if (error = delete_contents (wa->wa_Lock, TRUE)) goto fail;    /* delete any lone .info files */
  135.     if (!(parent = (struct WBArg *)malloc (sizeof (struct WBArg)))) goto fail;
  136.  
  137.     if (parent->wa_Lock = ParentDir (wa->wa_Lock))
  138.     {
  139.     if (NameFromLock (wa->wa_Lock, buf, 254))
  140.     {
  141.         UnLock (wa->wa_Lock);   /* UnLock the dir as it is about to be deleted */
  142.         wa->wa_Lock = NULL;     /* Tell everyone we've unlocked it. */
  143.  
  144.         parent->wa_Name = FilePart (buf);
  145.         set_current (NULL, SET_EXIT_DIR);
  146.         error = delete_file (parent);   /* delete ourselves */
  147.         if (error)              /* if failed, restore lock to directory */
  148.         {
  149.         BPTR olddir = CurrentDir (parent->wa_Lock);
  150.         wa->wa_Lock = Lock (parent->wa_Name, SHARED_LOCK); /* fingers crossed! */
  151.         CurrentDir (olddir);
  152.         }
  153.     } else error = IoErr();
  154.     UnLock (parent->wa_Lock);
  155.     }
  156.     else error = IoErr();
  157.  
  158.     fail:
  159.  
  160.     if (parent) free (parent);
  161.  
  162.     return (error);
  163. }
  164.  
  165. /* delete_icon -- delete an icon with name (MUST have a .info extension)    */
  166. /* which lives in dir locked in lock                        */
  167. LONG delete_icon (struct WBArg *wa)
  168. {
  169.     LONG error = 0;
  170.     char *dot;
  171.  
  172.     if (error = set_current (wa, SET_NEWFILE)) goto fail;
  173.  
  174.     if (dot = strrchr (wa->wa_Name, '.'))
  175.     {
  176.     *dot = '\0';    /* temporarily remove .info extension */
  177.     error = delete_file (wa);
  178.     *dot = '.';     /* restore .info, in case it is needed later */
  179.     }
  180.     else error = ERROR_OBJECT_WRONG_TYPE;
  181.  
  182.     fail:
  183.  
  184.     return (error);
  185. }
  186.  
  187. /* delete_file -- delete a file or dir given a lock to the dir + a name */
  188. /* Returns an error code from IoErr() if failed, or 0 for ok.           */
  189. LONG delete_file (struct WBArg *wa)
  190. {
  191.     LONG error = 0;
  192.     BOOL nofile = FALSE;
  193.  
  194.     if (error = set_current (wa, SET_NEWFILE)) goto fail;
  195.  
  196.     if ((wa->wa_Name[0] == '\0') || !(wa->wa_Name)) /* is it a directory? */
  197.     {
  198.     error = delete_dir (wa);
  199.     }
  200.     else
  201.     {
  202.     /* cd to lock and store old lock */
  203.     BPTR old_lock = CurrentDir (wa->wa_Lock);
  204.  
  205.     if (!DeleteFile (wa->wa_Name))       /* if delete file fails */
  206.     {
  207.         error = IoErr();
  208.  
  209.         if ((error == ERROR_DELETE_PROTECTED) && ignore_protection)
  210.         {
  211.         error = 0;
  212.         if (SetProtection (wa->wa_Name, 0))
  213.         {   /* try again to delete it */
  214.             if (!DeleteFile (wa->wa_Name)) error = IoErr();
  215.         }
  216.         else error = IoErr();
  217.         }
  218.  
  219.         if (error == ERROR_OBJECT_NOT_FOUND)
  220.         {
  221.         error = 0;
  222.         nofile = TRUE;     /* object is just an icon */
  223.         }
  224.     }
  225.  
  226.     if (!error)
  227.     {
  228.         char dotinfo[100];
  229.         strcpy (dotinfo, wa->wa_Name);
  230.         strcat (dotinfo, ".info");      /* create name of icon */
  231.  
  232.         if (!DeleteDiskObject (wa->wa_Name))    /* delete icon */
  233.         {
  234.         error = IoErr();
  235.  
  236.         if ((error == ERROR_DELETE_PROTECTED) && ignore_protection)
  237.         {
  238.             error = 0;
  239.             if (SetProtection (dotinfo, 0))
  240.             {    /* try again */
  241.             if (!DeleteDiskObject (wa->wa_Name)) error = IoErr();
  242.             }
  243.             else error = IoErr();
  244.         }
  245.  
  246.         /* If no icon was found and there was a file that was deleted */
  247.         if ((error == ERROR_OBJECT_NOT_FOUND) && !nofile)
  248.         {
  249.             BPTR fh = Open (dotinfo, MODE_NEWFILE); /* make pseudo icon */
  250.             if (fh)
  251.             {
  252.             Close (fh);
  253.             if (!DeleteDiskObject (wa->wa_Name))   /* now delete it! */
  254.             error = IoErr();
  255.             else error = 0;
  256.             }
  257.             else error = IoErr();
  258.         }
  259.         }
  260.     }
  261.     CurrentDir (old_lock);      /* restore old cd */
  262.     }
  263.  
  264.     fail:
  265.  
  266.     return (error);
  267. }
  268.  
  269.